/**
* @version v 3.6.3 2012/11/28
* @package Nerv Widgets, nw.js
* @author Manuele Castellan <manuele.castellan@gmail.com>
*
* @copyright    Copyright (C) Copyright (c) 2009 Manuele Castellan. All rights reserved.
* @license        GNU/GPLv3, see LICENSE
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
*/

if(!window.NW3){
 	var NW3 = function(){};
	NW3.version = '362';
	NW3.toString = function(){
		return "Nerv Widgets 3.6.2";
	};
}


/** config */
NW3.config = {};
NW3.config.dir = {
	plugin : 'plugins',
	lang : 'langs',
	theme : 'themes'
};



/** plugins loader */
NW3.plugin = {
	plugins : {
		'form'			: new Array ('form'),
		'tabs'			: new Array ('form','window','tabs'),
		'window'		: new Array ('form','window'),
		'toolbar'		: new Array ('form','toolbar'),
		'progressbar'	: new Array ('form', 'progressbar'),
		'calendar'		: new Array ('form','window','toolbar','table','calendar'),
		'toolbox'		: new Array ('form','window','tabs','toolbox'),
		'formreminder'	: new Array ('formreminder')
	},
	
	getRequired : function(val){
		arr = [];
		val = NW3.core.string.trim(val);
		
		switch(val){
			case '*':
				for(var p in NW3.plugin.plugins){
					arr = NW3.core.array.arrayMerge(arr, NW3.plugin.plugins[p]);
				}
				break;
			default:
				arr = NW3.plugin.plugins[val];
				break;
		}
		
		if(arr == undefined) return null;
		return arr;
	},
	
	arr_plugins : new Array(),	// array plugins
	arr_style	: new Array(),	// array style for plugins
	arr_options : new Object(),	// array options
	lang		: '',			// lang
	
	/** inizializza i plugins */
	init : function(options){
		NW3.plugin.arr_options = options;
		
		if(options.plugins){
			//NW3.style.load(options.style);
			
			arr_ = new Array();
			
			total = options.plugins.split(',');
			for(i=0;(total.length-1)>=i;i++){
				if(total[i] != "" && total[i] != undefined) arr_ = NW3.core.array.arrayMerge(arr_, NW3.plugin.getRequired(total[i]));
			}
			
			arr_ = NW3.core.array.arrayUnique(arr_);
			
			NW3.plugin.load(arr_);
			
			if(NW3.plugin.arr_options.style) NW3.plugin.loadCss(arr_);
			
			NW3.plugin.loadLang(NW3.plugin.arr_options.lang);
		}
	},
	
	/** carica array plugins */
	load : function(arr, pluginName, callback){
		arr = NW3.core.array.arrayDiff(arr, NW3.plugin.arr_plugins);
		
		if(NW3.core.array.isArray(arr)){
			NW3.plugin.arr_plugins = arr;
			arr_ = NW3.plugin.arr_plugins;
			url_ = NW3.core.getScriptUrl();
			
			callback_status = false;
			
			for(p=0;arr_.length>p;p++){
				url_plugin = url_ + NW3.config.dir.plugin + '/' + arr_[p] + '/' + arr_[p] + '.js';
				
				if (callback && pluginName == arr_[p]) {
					script = NW3.core.includeScript(url_plugin);
					// test for onload to trigger callback
					if (NW3.client.isGecko()) {
						script.onload = function(){
							callback();
						};
					}
					else {
						script.onreadystatechange = function(){
							if (script.readyState == 'loaded' || script.readyState == 'complete') {
								callback();
								callback_status = true;
							}
						};
					}
				}
				else {
					NW3.core.includeScript(url_plugin);
				}
			}
		}
	},
	
	/** carica lingua */
	loadLang : function(val){
		if(NW3.plugin.lang == ''){
			if(val != ""){
				NW3.plugin.lang = NW3.plugin.arr_options.lang;
				NW3.core.includeScript(url_ + NW3.config.dir.lang + '/' + NW3.plugin.arr_options.lang + '.js');
			}
		}
	},
	
	/** carica css plugins */
	loadCss : function(arr){
		arr = NW3.core.array.arrayDiff(arr, NW3.plugin.arr_style);
		
		for(p=0;arr.length>p;p++){
			NW3.core.includeCss(url_ + NW3.config.dir.theme + '/' + NW3.plugin.arr_options.style + '/' + arr[p] + '.css');
		}
	},
	
	/** array plugin richiesti */
	required : function(arr){
		if(NW3.core.array.isArray(arr)){
			arr_ = new Array();
			url_ = NW3.core.getScriptUrl();
			for(p=0;arr.length>p;p++){
				if(!NW3.core.array.inArray(arr[p], NW3.plugin.arr_plugins)){
					arr_[p] = arr[p];
					NW3.plugin.arr_plugins.push(arr[p]);
					NW3.core.includeScript(url_ + 'plugins/' + arr_[p] + '/' + arr_[p] + '.js');
				}
			}
			
			NW3.plugin.loadCss(arr_);
		}
	}
};

/** NW styles */
NW3.style = {
	name : null,
	
	load : function(val){
		if(val)	NW3.style.name = val;
		else NW3.style.name = 'xp';
		
		url_ = NW3.core.getScriptUrl();
		NW3.core.includeCss(url_ + 'styles/' + NW3.style.name + '/nw2.css');
	},
	
	getStyle : function(){
		return NW.style.name;
	}
};

/** ajax | Begin */

NW3.ajax = {
	/** Crea richiesta */
	createRequest : function() {
		var ua;
		if(window.XMLHttpRequest) {
			try {
				ua = new XMLHttpRequest();
			} catch(e) {
				ua = false;
			}
		} else if(window.ActiveXObject) {
			try {
				ua = new ActiveXObject("Microsoft.XMLHTTP");
			} catch(e) {
				ua = false;
			}
		}
		return ua;
	},
	
	/** Verifica il successo della risposta */
	isResponseSuccess : function(req) {
		return (typeof req == 'undefined')
			|| (typeof req.status == 'undefined')
			|| (req.status >= 200 && req.status < 300)
			|| req.status == 0;
	},
	
	/** Invia richiesta
	 * reqHeaders = [{ key : , value : }, ...]
	 * Content-Type supported:
	 * 		text/xml
	 * 		application/xml
	 * 		application/rdf+xml
	 * 		text/plain
	 * 		text/html
	 * 		application/octet-stream
	 */
	sendRequest : function(req, url, options) {
		url_request = NW3.client.getUrlParam(url);
		
		req.open(options.method, url_request);
		
		/* fix moz */
		if(!options.reqHeaders){
			if(req.overrideMimeType){
				options.reqHeaders.push({ key : 'Connection', value : 'close'});
			}
		}
		
		for (var h = 0; h < options.reqHeaders.length; h++){
			if(req.overrideMimeType){
				if(options.reqHeaders[h].key.toLowerCase() == 'content-type'){
					req.overrideMimeType(options.reqHeaders[h].value);
				}
			}
			req.setRequestHeader(options.reqHeaders[h].key, options.reqHeaders[h].value);
		}
		if(options.onComplete){
			req.onreadystatechange = function(){
				if(req.readyState == 4){
					if(NW3.ajax.isResponseSuccess(req)) options.onComplete(req);
				}
			};
		}
		if(!options.message) options.message = null;
		
		req.send(options.message);
		
		return req;
	},
	
	/**
	 * Richiesta diretta
	 * options = [{ key : , value : }, ...]
	 * Content-Type supported:
	 * 		text/xml
	 * 		application/xml
	 * 		application/rdf+xml
	 * 		text/plain
	 * 		text/html
	 * 		application/octet-stream
	 */
	Request : function(url, options) {
		var req = NW3.ajax.createRequest();
		
		reqHeaders = new Array();
		var reqHeaders = [
			{ key : 'X-Requested-With', value : 'XMLHttpRequest'},
			{ key : 'X-Prototype-Version', value : NW3.toString()}
		];
		
		if(!options.reqHeaders){
			// find content-type in the page
			obj = NW3.core.getElement('meta[http-equiv=content-type]');
			contentType = null;
			if(obj) contentType = obj.getAttribute('content');
			
			if(contentType) reqHeaders.push({ key : 'Content-type', value : contentType});
			else if(options.method.toLowerCase() == 'post'){
				reqHeaders.push({ key : 'Content-type', value : 'application/x-www-form-urlencoded'});
			}
		}
		
		options.reqHeaders = reqHeaders;
		
		NW3.ajax.sendRequest(req, url, options);
		
		return req;
	}
	
	/** Messaggio di log */
	/*MessageLog : function(url, message) {
		NW3.ajax.createRequest();
		
		options = {
			method : 'POST',
			message : message
		}
		
		reqHeaders = [{ key : "Content-Type", value : "text/plain;charset=UTF-8"}];
		NW3.ajax.sendRequest('/log', options, reqHeaders);
	}*/
};
/** ajax | End */


/* EventHelpers | Begin */
NW3.event = {
	domReady : function(fn) {
		if (NW3.event.domReady.loaded) return fn();

		var functions = NW3.event.domReady.load;
		if (!functions) functions = NW3.event.domReady.load = [];
		functions[functions.length] = fn;

		if (NW3.event.domReady.callback) return;
		NW3.event.domReady.callback = function() {
			if (NW3.event.domReady.loaded) return;

			NW3.event.domReady.loaded = true;
			if (NW3.event.domReady.timer) {
				clearInterval(NW3.event.domReady.timer);
				NW3.event.domReady.timer = null;
			}

			var functions = NW3.event.domReady.load;
			for (var i = 0, length = functions.length; i < length; i++) {
				var fn = functions[i];
				functions[i] = null;
				fn();
			}
			NW3.event.domReady.callback = NW3.event.domReady.load = null;
		};
	    
	    if (document.readyState && NW3.client.isWebKit()) {
			NW3.event.domReady.timer = setInterval(function(){
				if (/loaded|complete/.test(document.readyState)){
					NW3.core._domready.loaded();
				}
			}, 10);
	    }
	    else if (document.readyState && NW3.client.isIE()) {
			var src = (window.location.protocol == 'https:') ? '://0' : 'javascript:void(0)';
			document.write(
				'<script type="text/javascript" defer="defer" src="' + src + '"' + 
				' onreadystatechange="if (this.readyState == \'complete\') NW3.event.domReady.callback();"' + 
				'><\/script>');
		}
		else {
			if (window.addEventListener) {
				NW3.event.addEvent(document, "DOMContentLoaded", NW3.event.domReady.callback);
				NW3.event.addEvent(window, "load", NW3.event.domReady.callback);
			}
			else if (window.attachEvent) {
				window.attachEvent('onload', NW3.event.domReady.callback);
			}
			else {
				var fn = window.onload;
				NW3.event.addEvent(window, "load", function() {
					NW3.event.domReady.callback();
					if (fn) fn();
				});
			}
	    }
	},
	
	addEvent : function(el, evname, func) {
		if (el.attachEvent) {
			el.attachEvent("on" + evname, func);
		} else if (el.addEventListener) {
			el.addEventListener(evname, func, true);
		}
		else {
			el['on' + evname] = func;
		}
	},
	
	
	addEvents : function(el, evs, func) {
		for (var i = 0; i < evs.length; i++) {
			el.addEvent(evs[i], func);
		}
	},
	
	removeEvent : function(el, evname, func) {
		if (NW3.client.isIE()) {
			el.detachEvent("on" + evname, func);
		} else {
			el.removeEventListener(evname, func, true);
		}
	},
	
	removeEvents : function(el, evs, func) {
		for (var i = 0; i < evs.length; i++) {
			el.removeEvent(evs[i], func);
		}
	},
	
	stopEvent : function(el, ev) {
		if (NW3.client.isIE()) {
			ev.cancelBubble = true;
			ev.returnValue = false;
		} else {
			ev.preventDefault();
			ev.stopPropagation();
		}
	}
};
/* EventHelpers | End */


/**
 * drag and drop | Begin
 * o = object html to drag
 * oRoot = object html to start drag
 * */
NW3.event.Drag = function(o, oRoot){
	var obj = {
		el : o,
		root : oRoot,
		e : null,
		startX : null,
		startY : null,
		initialMouseX : null,
		initialMouseY : null,
		
		lockHorizontal : 0,
		lockVertical : 0,
		
		top : null,
		left : null,
		right : null,
		bottom : null,
		
		// esegue al drag dell'oggetto
		onDrag : null,
		onDragEnd : null,
		onChangePosition : null
	};
	
	// get top
	obj.getTop = function(){
		return obj.top;
	};
	
	// get left
	obj.getLeft = function(){
		return obj.left;
	};
	
	// get right
	obj.getRight = function(){
		return obj.right;
	};
	
	// get bottom
	obj.getBottom = function(){
		return obj.bottom;
	};
	
	// set onDrag
	obj.setOnDrag = function(val){
		obj.onDrag = val;
	};
	
	// set onDragEnd
	obj.setOnDragEnd = function(val){
		obj.onDragEnd = val;
	};
	
	// set onChangePosition
	obj.setOnChangePosition = function(val){
		obj.onChangePosition = val;
	};
	
	obj.dragOnly = function(val){
		val = val.toLowerCase();
		switch(val){
			case 'v':
			case 'y':
				obj.lockVertical = 1;
				break;
			case 'x':
			case 'w':
				obj.lockHorizontal = 1;
				break;
		}
	};
	
	obj.start = function(e){
		e = obj.fixE(e);
		
		if(obj.onDrag) obj.onDrag();
		
		obj.initialMouseX = NW3.client.mouseX(e);
		obj.initialMouseY = NW3.client.mouseY(e);
		
		document.onmousemove = obj.drag;
		document.onmouseup	 = obj.end;
		
		return false;
	};
	
	obj.drag = function(e){
		e = obj.fixE(e);
		
		eX = parseInt(NW3.client.mouseX(e));
		eY = parseInt(NW3.client.mouseY(e));
		
		var dX = parseInt(obj.root.style.left) +  parseInt(eX - obj.initialMouseX);
		var dY = parseInt(obj.root.style.top) + parseInt(eY - obj.initialMouseY);
		if(obj.lockHorizontal == 0) obj.root.style.top = dY + 'px';
		if(obj.lockVertical == 0) obj.root.style.left = dX + 'px';
		
		
		obj.initialMouseX	= eX;
		obj.initialMouseY	= eY;
		
		return false;
	};
	
	obj.end = function(){
		document.onmousemove = null;
		document.onmouseup   = null;
		
		// aggiorno dati posizione
		obj.top = obj.root.style.top;
		obj.left = obj.root.style.left;
		obj.right = obj.root.style.right;
		obj.bottom = obj.root.style.bottom;
		
		if(obj.onChangePosition) obj.onChangePosition();
		
		if(obj.onDragEnd) obj.onDragEnd();
	};
	
	obj.fixE = function(e)
	{
		if (typeof e == 'undefined') e = window.event;
		if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
		if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;
		return e;
	};
	
	// cerco oggetto draggabile
	if(!obj.root){
		var o = obj.el;
		// setto position: absolute
		obj.el.style.position = 'absolute';
	}
	else{
		var o = obj.root;
		// setto position: absolute
		obj.el.style.position = 'absolute';
	}
	
	// parte il drag
	o.onmousedown	= obj.start;
	
	obj.root = obj.el && obj.el != null ? obj.el : o ;
	
	return obj;
};
/* drag and drop | End */





// classe che gestisce effetti grafici su oggetti
NW3.rendering = {
	/* set opacity */
	setOpacity : function(el, opacity) {
		opacity = (opacity == 100)?99.999:opacity;
		// ie/Win
		el.style.filter = "alpha(opacity:"+opacity+")";
		// Safari<1.2, Konqueror
		el.style.KHTMLopacity = opacity/100;
		// Older Mozilla and Firefox
		el.style.Mozopacity = opacity/100;
		// Safari 1.2, newer Firefox and Mozilla, CSS3
		el.style.opacity = opacity/100;
	},
	
	/* aggiunge una classe */
	addClass : function(el, className) {
		// remove the class first, if already there
		NW3.rendering.removeClass(className);
		el.className += " " + className;
	},
	
	/* rimuove una classe */
	removeClass : function(el, className) {
		if (!(el && el.className)) {
			return;
		}
		var cls = el.className.split(" ");
		var ar = new Array();
		for (var i = cls.length; i > 0;) {
			if (cls[--i] != className) {
				ar[ar.length] = cls[i];
			}
		}
		el.className = ar.join(" ");
	},
	
	/* verifica se settata */
	hasClass : function(el, className) {
		if (!(el && el.className)) {
			return false;
		}
		var cls = el.className.split(" ");
		for (var i = cls.length; i > 0;) {
			if (cls[--i] == className) {
				return true;
			}
		}
		return false;
	}
};



NW3.core = {
	/** recupera oggetto nerv widgets */
	getScriptObj : function() {
		var script_ = document.getElementsByTagName("script");
		for (i=0;i<script_.length;i++){
			if(script_[i].src.indexOf('nw3.js') != -1){
				return script_[i];
				break;
			}
		}
	},
	
	/** recupera url nerv widgets */
	getScriptUrl : function() {
		var script_ = document.getElementsByTagName("script");
		for (i=0;i<script_.length;i++){
			if(script_[i].src.indexOf('nw3.js') != -1){
				return script_[i].src.replace('nw3.js', '');
				break;
			}
		}
	},
	
	/** aggiunge script */
	includeScript : function(file){
		var script  = document.createElement('script');
		
		script.setAttribute("type","text/javascript");
  		script.setAttribute("src", file);
		
		if (typeof script != "undefined") document.getElementsByTagName('head')[0].appendChild(script);
		
		return script;
	},
	
	/** aggiunge css */
	includeCss : function(file){
		var link  = document.createElement('link');
		
		link.setAttribute("rel", "stylesheet");
		link.setAttribute("type", "text/css");
		link.setAttribute("href", file);
		
		if (typeof link != "undefined") document.getElementsByTagName('head')[0].appendChild(link);
	}
};

/** client */
NW3.client = {
	/**
	 * get host
	 */
	getHost : function() {
		var url = window.location.href;
		var nohttp = url.split('//')[1];
		var hostPort = nohttp.split('/')[0];
		
		return hostPort;
	},
	
	/**
	 * get browser language
	 */
	getLang : function(){
		var theAgent = '';
		if (navigator.userLanguage) {
			theAgent = navigator.userLanguage;
		}
		else {
			theAgent = navigator.language;
		}
		
 		return theAgent;
	},
	/**
	 * get referrer url
	 */
	getUrlReferrer : function(){
		return document.referrer;
	},
	/**
	 * return value of a url param
	 */
	getUrlParam : function( paramName ){
		paramName = paramName.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
		var regexS = "[\\?&]"+paramName+"=([^&#]*)";
		var regex = new RegExp( regexS );
		var results = regex.exec( window.location.href );
		if( results == null )
			return paramName;
		else
			return results[1];
	},
	
	// get scroll position
	getScrollTop : function() {
		var scrOfY = 0;
		if( typeof( window.pageYOffset ) == 'number' ) {
			//Netscape compliant
			scrOfY = window.pageYOffset;
		} else if( document.body && document.body.scrollTop ) {
			//DOM compliant
			scrOfY = document.body.scrollTop;
		} else if( document.documentElement && document.documentElement.scrollTop ) {
			//IE6 standards compliant mode
			scrOfY = document.documentElement.scrollTop;
		}
		
		return scrOfY;
	},
	
	// get scroll position
	getScrollLeft : function() {
		var scrOfX = 0;
		if( typeof( window.pageYOffset ) == 'number' ) {
			//Netscape compliant
			scrOfX = window.pageXOffset;
		} else if( document.body && document.body.scrollLeft ) {
			//DOM compliant
			scrOfX = document.body.scrollLeft;
		} else if( document.documentElement && document.documentElement.scrollLeft ) {
			//IE6 standards compliant mode
			scrOfX = document.documentElement.scrollLeft;
		}
		
		return scrOfX;
	},
	
	// get KeyCode
	getKeyCode : function(e) {
		return e.keyCode;
	},
	
	// get CharCode
	getCharCode : function(e) {
		// fix bug for key 'F5'
		if(e.keyCode != 116){
			return String.fromCharCode(NW3.client.getKeyCode(e));
		}
	},
	
	// get window width
	getWidth : function() {
		var myWidth = 0;
		if( typeof( window.innerWidth ) == 'number' ) {
			//Non-IE
			myWidth = window.innerWidth;
			//myHeight = window.innerHeight;
		}
		else if( document.documentElement && ( document.documentElement.clientWidth ) ) {
			//IE 6+ in 'standards compliant mode'
			myWidth = document.documentElement.clientWidth;
			//myHeight = document.documentElement.clientHeight;
		}
		else if( document.body && ( document.body.clientWidth ) ) {
			//IE 4 compatible
			myWidth = document.body.clientWidth;
			//myHeight = document.body.clientHeight;
		}
		
		return myWidth;
	},
	
	// get window height
	getHeight : function() {
		var myHeight = 0;
		if( typeof( window.innerHeight ) == 'number' ) {
			//Non-IE
			//myWidth = window.innerWidth;
			myHeight = window.innerHeight;
		}
		else if( document.documentElement && ( document.documentElement.clientHeight ) ) {
			//IE 6+ in 'standards compliant mode'
			//myWidth = document.documentElement.clientWidth;
			myHeight = document.documentElement.clientHeight;
		}
		else if( document.body && ( document.body.clientHeight ) ) {
			//IE 4 compatible
			//myWidth = document.body.clientWidth;
			myHeight = document.body.clientHeight;
		}
		
		return myHeight;
	},
	
	// setto la variabile dei browsers
	ua : function() {
		return navigator.userAgent.toLowerCase();
	},
	
	// browsers
	isIE : function() {
		ua = this.ua();
		return !!((ua.indexOf("msie") != -1) && (ua.indexOf("opera") == -1) && (ua.indexOf("webtv") == -1)); 
	},
	isGecko : function() {
		ua = this.ua();
		return !!(ua.indexOf("gecko") != -1);
	},
	isSafari  : function() {
		ua = this.ua();
		return !! (ua.indexOf("safari") != -1);
	},
	isKonqueror  : function() {
		ua = this.ua();
		return !! (ua.indexOf("konqueror") != -1);
	},
	isOpera  : function(){
		ua = this.ua();
		return !! (ua.indexOf("opera") != -1);
	},
	isWebKit  : function(){
		ua = this.ua();
		return !! (ua.indexOf("webkit") != -1);
	},
	
	
	// recupera posizione mouse in base all'evento
	mouseX  : function(evt) {
		Event = (evt) ? evt : event;
		if (Event.pageX) return Event.pageX;
		else if (Event.clientX){
			return Event.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
		}
		else return null;
	},
	mouseY  : function(evt) {
		Event = (evt) ? evt : event;
		if (Event.pageY) return Event.pageY;
		else if (Event.clientY){
			return Event.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
		}
		else return null;
	}
};


/** string | Begin */
NW3.core.string = {
	/**
	 * Riempie una stringa con un'altra stringa
	 * portando la prima ad una lunghezza pre-determinata
	 * ---
	 * Se il valore di pad_length  � negativo
	 * oppure minore della stringa di input,
	 * non si ha nessun completamento.
	 * Il parametro pad_type , opzionale, 
	 * pu� valere STR_PAD_RIGHT, STR_PAD_LEFT,
	 * oppure STR_PAD_BOTH. Se non si indica pad_type
	 * lo si assume pari a STR_PAD_RIGHT.
	 */
	stringPad : function(input, pad_length, pad_string, pad_type){
	  input = String (input);
	  pad_string = pad_string != null ? pad_string : " ";
	  if (pad_string.length > 0)
	  {
	    var padi = 0;
	    pad_type = pad_type != null ? pad_type : "STR_PAD_RIGHT";
	    pad_length = parseInt (pad_length);
	    switch (pad_type)
	    {
	      case "STR_PAD_BOTH":
	        input = strPad (input
	                       , input.length + Math.ceil ((pad_length - input.length) / 2.0)
	                       , pad_string, "STR_PAD_RIGHT");
	     // break;  // kein break!
	      case "STR_PAD_LEFT":
	        var buffer = "";
	        for (var i = 0, z = pad_length - input.length; i < z; ++i)
	        {
	          buffer += pad_string.charAt(padi); // [padi] IE 6.x bug
	          if (++padi == pad_string.length)
	            padi = 0;
	        }
	        input = buffer + input;
	        break;
	      default:
	        for (var i = 0, z = pad_length - input.length; i < z; ++i)
	        {
	          input += pad_string.charAt(padi);
	          if (++padi == pad_string.length)
	            padi = 0;
	        }
	        break;
	    }
	  }
	  return input;
	},
	
	/**
	 * Verifica se una stringa
	 */
	isString : function(str){
		return (typeof(str) == 'string');
	},
	
	/**
	 * Verifica se numero o una stringa numerica
	 */
	isNumeric : function(num){
		var exp = new RegExp("^[0-9-.]*$","g");
		return exp.test(num);
	},
	
	
	/**
	 * Verifica se una variabile di tipo integer
	 * bool isInt ( mixed var )
	 */
	isInt : function(vari) {
		if (vari == "") return;
		for (i = 0 ; i < vari.length ; i++) {
			if ((vari.charAt(i) < '0') || (vari.charAt(i) > '9')) return false;
		}
		return true;
	},
	
	isDate : function(y, m, d){
		if(typeof y == "string" && m instanceof RegExp && d){
			if(!m.test(y)) return 1;
				y = RegExp["$" + d.y], m = RegExp["$" + d.m], d = RegExp["$" + d.d];
			}
		d = Math.abs(d) || 0, m = Math.abs(m) || 0, y = Math.abs(y) || 0;
		return arguments.length != 3 ? 1 : d < 1 || d > 31 ? 2 : m < 1 || m > 12 ? 3 : /4|6|9|11/.test(m) && d == 31 ? 4
		: m == 2 && (d > ((y = !(y % 4) && (y % 1e2) || !(y % 4e2)) ? 29 : 28)) ? 5 + !!y : 0;
	},
	
	/** converte una stringa in data (formato datetime) */
	stringToDate : function(str_datetime) {
		var re_date = /^(\d+)[- \/.](\d+)[- \/.](\d+)\s+(\d+)\:(\d+)\:(\d+)$/;
		if (!re_date.exec(str_datetime))
			return alert("Invalid Datetime format: "+ str_datetime);
		return (new Date (RegExp.$1, RegExp.$2-1, RegExp.$3,   RegExp.$4, RegExp.$5, RegExp.$6));
	},
	
	/** converte una stringa-data secondo il formato in formato datetime */
	parseDate : function(strdate, format){
		if(format != "" && format != null && format != 'undefined') format_ = format+"";
		else format_ = 'Y/m/d H:i:s';
		
		
		/**
		 * formatta data in una stringa
		 * Y - anno, 4 cifre; i.e. "1999"
		 * y - anno, 2 cifre; i.e. "99"
		 * n - mese senza eventuali zero; i.e. "1" a "12"
		 * m - mese; i.e. "01" a "12"
		 * M - mese, testuale, 3 lettere; i.e. "Jan"
		 * j - giorno del mese senza eventuali zero; i.e. "1" a "31"
		 * d - giorno del mese, 2 cifre senza tralasciare gli zero; i.e. "01" a "31"
		 * D - giorno della settimana, testuale, 3 lettere; i.e. "Fri"
		 * w - giorno della settimana, numerico, i.e. "0" (Domenica) a "6" (Sabato)
		 * W - ISO-8601 Numero della settimana dell'anno, le settimane iniziano il luned� (aggiunto in PHP 4.1.0) (Sabato)
		 * G - ora, formato a 24-ore senza eventuali zero; i.e. "0" a "23"
		 * H - ora, formato a 24-ore; i.e. "00" a "23"
		 * h - ora, formato a 12-ore; i.e. "01" a "12"
		 * i - minuti; i.e. "00" a "59"
		 * s - secondi; i.e. "00" a "59"
		 */
		
		
		var re_date_ = new String;
		var regArr = new Array;
		
		var indice = 0;
		var year = '';
		var month = '';
		var day = '';
		var hour = '';
		var minute = '';
		var second = '';
		
		
		for(f=0; f<format_.length; f++){
			switch(format_.charAt(f)){
				case 'Y':
				case 'y':
					for(ind=indice; ind<strdate.length; ind++){
						if(NW3.core.string.isNumeric(strdate.charAt(ind))) year += strdate.charAt(ind);
						else{
							indice = ind;
							break;
						}
					}
					break;
				case 'n':
				case 'm':
					for(ind=indice; ind<strdate.length; ind++){
						if(NW3.core.string.isNumeric(strdate.charAt(ind))) month += strdate.charAt(ind);
						else{
							indice = ind;
							break;
						}
					}
					break;
				case 'j':
				case 'd':
				case 'w':
					for(ind=indice; ind<strdate.length; ind++){
						if(NW3.core.string.isNumeric(strdate.charAt(ind))) day += strdate.charAt(ind);
						else{
							indice = ind;
							break;
						}
					}
					break;
				case 'G':
				case 'H':
				case 'h':
					
					for(ind=indice; ind<strdate.length; ind++){
						if(NW3.core.string.isNumeric(strdate.charAt(ind))) hour += strdate.charAt(ind);
						else{
							indice = ind;
							break;
						}
					}
					break;
				case 'i':
					
					for(ind=indice; ind<strdate.length; ind++){
						if(NW3.core.string.isNumeric(strdate.charAt(ind))) minute += strdate.charAt(ind);
						else{
							indice = ind;
							break;
						}
					}
					break;
				case 's':
					
					for(ind=indice; ind<strdate.length; ind++){
						if(NW3.core.string.isNumeric(strdate.charAt(ind))) second += strdate.charAt(ind);
						else{
							indice = ind;
							break;
						}
					}
					break;
				case 'M':
					regArr[1] = 'm';
					re_date_ += '(\S+)';
					break;
				case 'D':
					regArr[2] = 'd';
					re_date_ += '(\S+)';
					break;
				default:
					indice = indice + 1;
					break;
			}
		}
		
		year = (year == '') ? 2000 : year;
		month = (month == '') ? 00 : month;
		day = (day == '') ? 00 : day;
		hour = (hour == '') ? 00 : hour;
		minute = (minute == '') ? 00 : minute;
		second = (second == '') ? 00 : second;
		
		result = (year + '/' + month +'/'+ day +' '+ hour +':'+ minute +':'+ second);
		
		return result;
	},
	
	/** Conta le parola in una stringa */
	countWords : function(str, stripTags){
		if(stripTags) str = NW3.core.string.stripTags(str); //strip HTML
		str = NW3.core.string.trim(str);
		
		return str.match(/^ *$/) ? 0 : str.split(/\s+/g).length;
	},
	
	/** Conta le lettere in una stringa */
	countChars : function(str, onlyChars){
		if(onlyChars){
			str = str.replace(/\s+/g,"");
		}
		
		return str.length;
	},
	
	/** Rimuove gli spazi (ed altri caratteri) all'inizio e alla fine di una stringa */
	trim : function(str) {
		if(str) return str.replace(/^\s+|\s+$/g,"");
		return false;
	},
	
	/** Rimuove gli spazi (o altri caratteri) dall'inizio di una stringa */
	lTrim : function(str) {
		if(str) return str.replace(/^\s+/g,"");
		return false;
	},
	
	/** Rimuove gli spazi (ed altri caratteri) dalla fine della stringa */
	rTrim : function(str) {
		if(str) return str.replace(/\s+$/g,"");
		return false;
	},
	
	/** Rimuove i tag HTML e PHP da una stringa */
	stripTags : function(str){
		re = /<\S[^><]*>/gi;
		
		return str.replace(re, "");
	},
	
	/** Recupera l'estensione di un file */
	fileExt : function(file){
		lfile = file.split('.');
		ccfile = lfile.length -1;
		return lfile[ccfile];
	},
	
	/** Recupera parametri in get */
	getParameter : function( queryString, parameterName ) {
		object = new Object();
		
		qs = queryString.split("?");
		
		for(i=0; qs.length>i; i++){
			vari = qs[i].split("=");
			if(vari[0] == parameterName) return vari[1];
		}
		
		return null;
	},
	
	/** Convert ascii chars to text */
	asciiToText : function( queryString ) {
		match = queryString.match(/&#([0-9]*);/g);
	 
	    if (match != undefined && match != null) {
		    for(var i=0; i<match.length; i++){
				var chr_code = match[i];
				if ( chr_code != undefined && NW3.core.string.isString(chr_code) && chr_code.length > 0 && chr_code != '' ) {
					chr_code = chr_code.replace(/&#([\d]*?);/ig, "$1");
					chr = NW3.core.string.getCharCode(chr_code);
					queryString = queryString.replace(match[i], chr);
				}
		     }
	    }
	    
	    return queryString;
	}
};
/* string | End */


/* number | Begin */
NW3.core.number = {
	/**
	 * Verifica se numero o stringa numerica
	 */
	isNumeric : function(num){
		var exp = new RegExp("^[0-9-.]*$","g");
		return exp.test(num);
	},
	
	
	/**
	 * Verifica se di tipo integer
	 * bool isInt ( mixed var )
	 */
	isInt : function(vari) {
		if (vari == "") return;
		for (i = 0 ; i < vari.length ; i++) {
			if ((vari.charAt(i) < '0') || (vari.charAt(i) > '9')) return false;
		}
		return true;
	},
	
	validate : function(pnumber){
		pnumber = pnumber.replace(",",".");
		pnumber = pnumber.replace(/[^\d\.]/g, "");
		
		var myregexp = /\d*?\.\d*/;
		var match = myregexp.exec(pnumber);
		if (match != null) {
			return match;
		} else {
			return pnumber;
		}
	},
	
	formatNumber : function(Numero, Decimales) {
		Numero = Numero.replace(",",".");
		nume = Numero.toString().split('.');
		
		if(NW3.core.array.isArray(nume) && nume.length > 1){
			entero = nume[0];
			decima = nume[1];
		}
		else {
			if(nume > 0) entero = nume;
			else entero = 0;
			decima = 0;
		}
		
		decima = decima.toString().substring(0, Decimales);
		
		decima = NW3.core.string.stringPad(decima, Decimales, '0', 'stringPad_RIGHT');
		
		num=entero+'.'+decima;
		num = num.replace(/(\d*?)(\.)$/g, "$1");
		return num;
	}
};


/* object | Begin */
NW3.core.object = {
	/** extend object */
	extend : function(destination, source) {
		for (var property in source){
			destination[property] = source[property];
			return destination;
		}
	},
	
	clone : function(obj){
        if(obj == null || !NW3.core.object.isObject(obj)) return obj;
		
		return obj.cloneNode(true);
	},
	
	isObject : function(str){
		if(str == undefined) return false;
		if(NW3.core.array.isArray(str)) {
			return false;
		} else {
			return (str !== null) && (typeof( str ) == 'object');
		}
	},
	
	/** trova posizione top dell'oggetto */
	getPosTop : function(el) {
		if(NW3.core.object.isObject(el)){
			var curtop = 0;
			if (el.offsetParent) {
				curtop = el.offsetTop;
				while (el = el.offsetParent) {
					curtop += el.offsetTop;
				}
			}
			return curtop;
		}
		else return false;
	},
	
	/** trova posizione left dell'oggetto */
	getPosLeft : function(el) {
		var curleft = 0;
		if (el.offsetParent) {
			curleft = el.offsetLeft;
			while (el = el.offsetParent) {
				curleft += el.offsetLeft;
			}
		}
		return curleft;
	},
	
	/** elimina nodo */
	removeElement : function(node) {
		var removed = node.parentNode.removeChild(node); 
		return removed;
	},
	
	/** elimina tutti i nodi figli */
	removeChildsNodes : function(node) {
		if ( node.hasChildNodes() ){
		    while ( node.childNodes.length >= 1 ){
		        if(!node.removeChild( node.firstChild )) return false;       
		    } 
		}
		
		return true;
	},
	
	/** outerHtml setter */
	setOuterHTML : function(element,html){
		if(NW3.client.isGecko()){
			var range=element.ownerDocument.createRange();
			range.setStartBefore(element);
			var fragment=range.createContextualFragment(html);
			element.parentNode.replaceChild(fragment,element);
		}
		else{
			element.outerHTML=html;
		}
	},
	
	/** outerHtml getter */
	getOuterHTML : function(node) {
		var str = "";
		
		var _leafElems = ["IMG", "HR", "BR", "INPUT"];
		var leafElems = {};
		for (var i=0; i<_leafElems.length; i++)
			leafElems[_leafElems[i]] = true;
		
		switch (node.nodeType) {
			case 1: // ELEMENT_NODE
				str += "<" + node.nodeName;
				for (var i=0; i<node.attributes.length; i++) {
					if (node.attributes.item(i).nodeValue != null) {
						str += " ";
						str += node.attributes.item(i).nodeName;
						str += "=\"";
						str += node.attributes.item(i).nodeValue;
						str += "\"";
					}
				}
	
				if (node.childNodes.length == 0 && leafElems[node.nodeName])
					str += ">";
				else {
					str += ">";
					for (var i=0; i<node.childNodes.length; i++)
					str += NW3.core.object.getOuterHTML(node.childNodes.item(i));
					//str += getInnerHTML(node);
					str += "</" + node.nodeName + ">";
				}
				break;
					
			case 3:	//TEXT_NODE
				str += node.nodeValue;
				break;
				
			case 4: // CDATA_SECTION_NODE
				str += "<![CDATA[" + node.nodeValue + "]]>";
				break;
						
			case 5: // ENTITY_REFERENCE_NODE
				str += "&" + node.nodeName + ";";
				break;
	
			case 8: // COMMENT_NODE
				str += "<!--" + node.nodeValue + "-->";
				break;
		}
	
		return str;
	},
	
	/** Print Object */
	print : function(obj){
		// creo div temporaneo
		var tmpDiv = document.createElement('div');
		// nascondo il div temporaneo
		tmpDiv.style.display = 'none';
		// setto id
		tmpDiv.id = "NW-tmp-HTML-dIv" + NW3.version;
		// inserisco nella pagina
		document.write(NW3.core.object.getOuterHTML(tmpDiv));
		// recupero oggetto temporaneo
		var tmpDiv = NW3.getElement('#NW-tmp-HTML-dIv' + NW3.version);
		// inserisco oggetto
		tmpDiv.parentNode.insertBefore(obj, tmpDiv);
		// elimino il div temporaneo
		tmpDiv.parentNode.removeChild(tmpDiv);
	},
	
	/** Replace Object */
	replace : function(targetElement, newElement){
		if(typeof(newElement) == "string"){
			newElement = NW3.getElement(newElement);
		}
		if(typeof(targetElement) == "string"){
			targetElement = NW3.getElement(targetElement);
		}
		
		NW3.core.object.insertBefore(newElement, targetElement);
		targetElement.parentNode.removeChild(targetElement);
	},
	
	/** Insert After */
	insertAfter : function(newElement, targetElement) {
		var parent = targetElement.parentNode;
		if(parent.lastchild == targetElement) {
			parent.appendChild(newElement);
		} else {
			NW3.core.object.insertBefore(newElement, targetElement.nextSibling);
		}
	},
	
	/** Insert Before */
	insertBefore : function(newElement, targetElement){
		if(typeof(newElement) == "string"){
			newElement = NW3.getElement(newElement);
		}
		if(typeof(targetElement) == "string"){
			targetElement = NW3.getElement(targetElement);
		}
		
		targetElement.parentNode.insertBefore(newElement, targetElement);
	},
	
	/** Append Child */
	appendChild : function(newElement, targetElement){
		if(typeof(newElement) == "string"){
			newElement = NW3.getElement(newElement);
		}
		if(typeof(targetElement) == "string"){
			targetElement = NW3.getElement(targetElement);
		}
		
		if (targetElement.nodeType == 1) targetElement.appendChild(newElement);
	}
};
/* object | End */

/* array | Begin */
NW3.core.array = {
	isArray : function(obj) {
		if(!obj) return false;
		else if(typeof obj == 'string') return false;
		else if(obj instanceof Array) return true;
		
		/*if (obj.constructor.toString().indexOf("Array") == -1) return false;
		else return true;*/
		
		/*res = obj && typeof obj.pop=="function" && obj.length;
		if(res > 0) return true;
		else if (obj && obj.constructor.toString().indexOf("Array") == -1) return false;
		else return false;*/
	},
	
	inArray : function (value, array) {
		var i;
		for (i=0; i < array.length; i++) {
			if (array[i] === value) {
				return true;
			}
		}
		return false;
	},
	
	arrayUnique : function (array) {
		var target = new Array();
		
		for(var i = 0; i < array.length; i++) {
			if(array[i] != ''){
				if(!NW3.core.array.inArray(array[i], target)) {
					target.push(array[i]);
				}
			}
		}
		
		return target;
	},
	
	arrayMerge : function (one, two) {
		return one.concat(two);
	},
	
	/**
	 * Ricerca un dato valore in un array e ne restituisce la chiave corrispondente, se la ricerca ha successo
	 */
	arraySearch : function(val, array){
	    for(var i in array){
	        if(array[i]==val){
	        	return i;
	        }    
	    }
	    return false;
	},
	
	/**
	 * Computes the difference of arrays
	 */
	arrayDiff : function() {
	    var ar1 = arguments[0];
	    var a1 = '';
	    var arr = {};
	    var i = 1;
	    var a = '';
	    var resultArr = new Array();
		
	    ar1keys:
	    for (a1 in ar1) {
	        for (i = 1; i < arguments.length; i++) {
	            arr = arguments[i];
	            
	            for (a in arr) {
	                if (arr[a] === ar1[a1]) {
	                    continue ar1keys; 
	                }
	            }
	            
	            resultArr[a1] = ar1[a1];
	        }
	    }
		
	    return resultArr;
	}
};
/* array | End */

/* date | Begin */
NW3.core.date = {
	/**
	 * converte una data in formato stringa (datetime)
	 */
	dateToString : function(date) {
		return (new String (
				date.getFullYear() + "/"
				+ (date.getMonth() < 9 ? '0' : '') + (date.getMonth()+1) + "/"
				+ (date.getDate() < 9 ? '0' : '') + date.getDate()
				
				+ date.getHours() + ":"
				+ date.getMinutes() + ":"
				+ date.getSeconds()
			)
		);
	},
	
	/**
	 * formatta data in una stringa
	 * Y - anno, 4 cifre; i.e. "1999"
	 * y - anno, 2 cifre; i.e. "99"
	 * n - mese senza eventuali zero; i.e. "1" a "12"
	 * m - mese; i.e. "01" a "12"
	 * M - mese, testuale, 3 lettere; i.e. "Jan"
	 * j - giorno del mese senza eventuali zero; i.e. "1" a "31"
	 * d - giorno del mese, 2 cifre senza tralasciare gli zero; i.e. "01" a "31"
	 * D - giorno della settimana, testuale, 3 lettere; i.e. "Fri"
	 * w - giorno della settimana, numerico, i.e. "0" (Domenica) a "6" (Sabato)
	 * W - ISO-8601 Numero della settimana dell'anno, le settimane iniziano il luned� (aggiunto in PHP 4.1.0) (Sabato)
	 * G - ora, formato a 24-ore senza eventuali zero; i.e. "0" a "23"
	 * H - ora, formato a 24-ore; i.e. "00" a "23"
	 * h - ora, formato a 12-ore; i.e. "01" a "12"
	 * i - minuti; i.e. "00" a "59"
	 * s - secondi; i.e. "00" a "59"
	 */
	dateFormat : function(date, format) {
		var DAY_NAMES = [
			NW3.lang.Sunday,
			NW3.lang.Monday,
			NW3.lang.Tuesday,
			NW3.lang.Wednesday,
			NW3.lang.Thursday,
			NW3.lang.Friday,
			NW3.lang.Saturday
		];
		
		var MONTH_NAMES = [
			NW3.lang.January,
			NW3.lang.February,
			NW3.lang.March,
			NW3.lang.April,
			NW3.lang.May,
			NW3.lang.June,
			NW3.lang.July,
			NW3.lang.August,
			NW3.lang.September,
			NW3.lang.October,
			NW3.lang.November,
			NW3.lang.December
		];
		
		function LZ(x) {
			return(x<0||x>9?"":"0")+x;
		}
		
		var date_ = new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());
		//document.write(date_);
		date_.setMonth(date_.getMonth());
		
		if(format != "" && format != null && format != 'undefined') format_ = format+"";
		else format_ = 'Y/m/d H:i:s';
		
		var result="";
		var i_format=0;
		var c="";
		var token="";
		var y=date_.getYear()+"";
		var M=date_.getMonth();
		var d=date_.getDate();
		var E=date_.getDay();
		var H=date_.getHours();
		var m=date_.getMinutes();
		var s=date_.getSeconds();
		var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
		// Convert real date parts into formatted versions
		var value=new Object();
		if (y.length < 4) {
			y=""+(y-0+1900);
		}
		// anni
		//value["y"]=""+y;
		value["Y"]=y;								//  Y - anno, 4 cifre; i.e. "1999"
		value["y"]=y.substring(2,4);				//  y - anno, 2 cifre; i.e. "99"
		
		// mesi
		value["n"]=M+1;								//	n - mese senza eventuali zero; i.e. "1" a "12"
		value["m"]=LZ(M+1);							//	m - mese; i.e. "01" a "12"
		value["M"]=MONTH_NAMES[M].substr(0,3);		//	M - mese, testuale, 3 lettere; i.e. "Jan"
		//value["NNN"]=MONTH_NAMES[M+11];
		
		// giorni
		value["j"]=d;								//	j - giorno del mese senza eventuali zero; i.e. "1" a "31"
		value["d"]=LZ(d);							//	d - giorno del mese, 2 cifre senza tralasciare gli zero; i.e. "01" a "31"
		value["D"]=DAY_NAMES[E+7];					//	D - giorno della settimana, testuale, 3 lettere; i.e. "Fri"
		value["w"]=E;								//	w - giorno della settimana, numerico, i.e. "0" (Domenica) a "6" (Sabato)
		//value["w"]=E;								//	W - ISO-8601 Numero della settimana dell'anno, le settimane iniziano il luned� (aggiunto in PHP 4.1.0) (Sabato)
		//value["EE"]=DAY_NAMES[E];
		
		// ore
		value["G"]=H;								//	G - ora, formato a 24-ore senza eventuali zero; i.e. "0" a "23"
		value["H"]=LZ(H);							//	H - ora, formato a 24-ore; i.e. "00" a "23"
		if (H==0){
			value["h"]=12;
		}
		else if (H>12){
			value["h"]=H-12;
		}
		else {
			value["h"]=H;
		}
		value["h"]=LZ(value["h"]);					//	h - ora, formato a 12-ore; i.e. "01" a "12"
		if (H>11){
			value["K"]=H-12;
		} else {
			value["K"]=H;
		}
		
		if (H > 11) {
			value["a"]="PM";
		}
		else {
			value["a"]="AM";
		}
		
		// minuti
		value["ij"]=m;								
		value["i"]=LZ(m);							//	i - minuti; i.e. "00" a "59"
		
		// secondi
		value["sj"]=s;
		value["s"]=LZ(s);							//	s - secondi; i.e. "00" a "59"
		while (i_format < format_.length) {
			c=format_.charAt(i_format);
			token="";
			while ((format_.charAt(i_format)==c) && (i_format < format_.length)) {
				token += format_.charAt(i_format++);
			}
			if (value[token] != null) {
				result=result + value[token];
			}
			else {
				result=result + token;
			}
		}
		return result;
	}
};
/* date | End */

NW3.core._getElementsByClassName = function(classname, node) {
	if(!node) node = document.getElementsByTagName("body")[0];
	var a = new Array();
	var re = new RegExp('\\b' + classname + '\\b');
	var els = node.getElementsByTagName("*");
	for(var i=0,j=els.length; i<j; i++){
		if(re.test(els[i].className)) a.push(els[i]);
	}
	
	return a;
};

/**
 * Gets one element that match with attributes
 */
NW3.core.getElement = function(list, obj) {
	arr = NW3.core.getElements(list, obj);
	if(NW3.core.array.isArray(arr)) return arr[0];
	else return false;
};
/**
 * Gets all the elements that match with attributes
 */
NW3.core.getElements = function(list, obj) {
   if (!obj)
      var obj = document;
   
   var tagNames = list.split(',');
   var resultArray = new Array();
   
   for (var i=0;i<tagNames.length;i++) {
       subject = tagNames[i];
	   if (match = subject.match(/(.*)\[(.*[a-zA-Z0-9])(.*[=\^$!])'?(.*[a-zA-Z0-9])'?\]/)) {
	   		tagNames[i] = match;
	   }
	   else if (match = subject.match(/#(.*)/)) {
	   		resultArray.push( document.getElementById(match[1]) );
	   }
	   else if (match = subject.match(/.(.*)/)) {
	   		resultArray = NW3.core.array.arrayMerge(resultArray, NW3.core._getElementsByClassName(match[1]));
	   }
	   else{
	   		tagNames[i] = new Array(tagNames[i], tagNames[i]);
	   }
	   
	   // recupero i tags dal nome
	   var tags = obj.getElementsByTagName(tagNames[i][1]);
	   
	   var resultTag = null;
	   for (var j=0;j<tags.length;j++) {
	   		if(tagNames[i][3]){
				var attr = null;
				tagNames[i][2] = tagNames[i][2].toLowerCase();
				switch(tagNames[i][2]){
					case 'class':
						attr = tags[j].className;
						break;
					case 'http-equiv':
						if(NW3.client.isIE()) attr = tags[j].getAttribute('httpEquiv');
						break;
					default:
						attr = tags[j].getAttribute(tagNames[i][2]);
						break;
				}
				if(attr){
					attr = attr.toLowerCase();
					switch(tagNames[i][3]){
						// equal to
						case '=':
							if(attr == tagNames[i][4].toLowerCase()) resultTag = tags[j];
							break;
						// start with
						case '^=':
							req = new RegExp('(^'+tagNames[i][4].toLowerCase()+')');
							if (attr.match(req)) {
								resultTag = tags[j];
							}
							break;
						// end with
						case '$=':
							req = new RegExp('('+tagNames[i][4].toLowerCase()+'$)');
							if (attr.match(req)) {
		  						resultTag = tags[j];
							}
							break;
						// not equal to
						case '<>':
						case '!=':
							if(attr != tagNames[i][4].toLowerCase()) resultTag = tags[j];
							break;
						// like to - contains
						case '%=':
							req = new RegExp(tagNames[i][4].toLowerCase());
							if (attr.match(req)) {
		  						resultTag = tags[j];
							}
						// not start with
						case '!^=':
							req = new RegExp('(^'+tagNames[i][4].toLowerCase()+')');
							if (!attr.match(req)) {
								resultTag = tags[j];
							}
							break;
						// not end with
						case '!$=':
							req = new RegExp('('+tagNames[i][4].toLowerCase()+'$)');
							if (!attr.match(req)) {
		  						resultTag = tags[j];
							}
							break;
						// not like to
						case '!%=':
							req = new RegExp(tagNames[i][4].toLowerCase());
							if (!attr.match(req)) {
		  						resultTag = tags[j];
							}
					}
					if(resultTag) resultArray.push(resultTag);
				}
			}
			else {
				resultArray.push(tags[j]);
			}
       }
   }
   
   if(resultArray.length == 0) resultArray = null;
   return resultArray;
};

NW3.core.object.extend(NW3, {
	getElement : function(list, obj){
		return NW3.core.getElement(list, obj);
	},
	
	getElements : function(list, obj){
		return NW3.core.getElements(list, obj);
	}
});

/* cookie | Begin */
NW3.cookie = {
	// write cookie
	write : function(name,value,days) {
		if (days) {
			var date = new Date();
			date.setTime(date.getTime() + (days*24*60*60*1000));
			var expires = "; expires=" + date.toGMTString();
		}
		else expires = "";
		
		document.cookie = name + "=" + value + expires + ";";
	},

	// read cookie
	read : function(name) {
	  var nameEQ = name + "=";
	  var ca = document.cookie.split(';');
	  
	  for(var i=0;i < ca.length;i++) {
	    var c = ca[i];
	    while (c.charAt(0)==' ') c = c.substring(1,c.length);
	    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	  }
	  return "null";
	},

	// erase cookie
	erase : function(name) {
		NW3.cookie.write(name,"",-1);
	}
};
/* cookie | End */


/* utils | Begin */
NW3.utils = {};

NW3.utils.Mysql = {
	/**
	 * convert mysql datetime in date object
	 */
	mysqlDatetimeToDate : function(datetime) {
		var regex = /^([0-9]{2,4})-([0-1][0-9])-([0-3][0-9]) (?:([0-2][0-9]):([0-5][0-9]):([0-5][0-9]))?$/;
		var parts = datetime.replace(regex, "$1 $2 $3 $4 $5 $6").split(' ');
		return new Date(parts[0], parts[1]-1, parts[2], parts[3], parts[4], parts[5]);
	}
};

NW3.utils.Password = {
	/**
	 * random password generator
	 * default length: 8
	 */
	generateRandom : function(length, format) {
	    _getRandomNum = function() {
		    var rndNum = Math.random();
		    rndNum = parseInt(rndNum * 1000);
		    rndNum = (rndNum % 94) + 33;
		            
		    return rndNum;
		};
		
		_checkPunc = function(num) {
		    if ((num >=33) && (num <=47)) { return true; }
		    if ((num >=58) && (num <=64)) { return true; }    
		    if ((num >=91) && (num <=96)) { return true; }
		    if ((num >=123) && (num <=126)) { return true; }
		    
		    return false;
		};
	    
	    
	    var len=(length)?length:8;
	    var strCase=(format)?format:false;
	    
	    var sPassword = "";
	    
	    for (i=0; i < len; i++) {
	    
	        numI = _getRandomNum();
	        while (_checkPunc(numI)) {
	        	numI = _getRandomNum();
	        }
			
	        sPassword = sPassword + String.fromCharCode(numI);
	    }
	    
	    if(strCase){
		    switch(strCase){
		    	case 'lower':
		    		sPassword = sPassword.toLowerCase();
		    		break;
		    	case 'upper':
		    		sPassword = sPassword.toUpperCase();
		    		break;
		    }
	    }
	    
	    return sPassword;
	}
};

NW3.utils.Base64 = {
	/**
	 * Codifica una stringa in MIME base64
	 * string base64_encode ( string str )
	 */
	encode : function(str) {
	    var base64EncodeChars = [
		    "A", "B", "C", "D", "E", "F", "G", "H",
		    "I", "J", "K", "L", "M", "N", "O", "P",
		    "Q", "R", "S", "T", "U", "V", "W", "X",
		    "Y", "Z", "a", "b", "c", "d", "e", "f",
		    "g", "h", "i", "j", "k", "l", "m", "n",
		    "o", "p", "q", "r", "s", "t", "u", "v",
		    "w", "x", "y", "z", "0", "1", "2", "3",
		    "4", "5", "6", "7", "8", "9", "+", "/"
		];
		
		var out, i, j, len;
	    var c1, c2, c3;
	
	    len = str.length;
	    i = j = 0;
	    out = [];
	    while (i < len) {
	        c1 = str.charCodeAt(i++) & 0xff;
	        if (i == len)
	        {
	            out[j++] = base64EncodeChars[c1 >> 2];
	            out[j++] = base64EncodeChars[(c1 & 0x3) << 4];
	            out[j++] = "==";
	            break;
	        }
	        c2 = str.charCodeAt(i++) & 0xff;
	        if (i == len)
	        {
	            out[j++] = base64EncodeChars[c1 >> 2];
	            out[j++] = base64EncodeChars[((c1 & 0x03) << 4) | ((c2 & 0xf0) >> 4)];
	            out[j++] = base64EncodeChars[(c2 & 0x0f) << 2];
	            out[j++] = "=";
	            break;
	        }
	        c3 = str.charCodeAt(i++) & 0xff;
	        out[j++] = base64EncodeChars[c1 >> 2];
	        out[j++] = base64EncodeChars[((c1 & 0x03) << 4) | ((c2 & 0xf0) >> 4)];
	        out[j++] = base64EncodeChars[((c2 & 0x0f) << 2) | ((c3 & 0xc0) >> 6)];
	        out[j++] = base64EncodeChars[c3 & 0x3f];
	    }
	    return out.join('');
	},
	
	
	/**
	 * Decodifica una stringa da MIME base64
	 * string base64_decode ( string str )
	 */
	decode : function(str) {
	    var base64DecodeChars = [
		    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
		    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
		    -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
		    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
		    -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
		    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
		];
		
		var c1, c2, c3, c4;
	    var i, j, len, out;
	
	    len = str.length;
	    i = j = 0;
	    out = [];
	    while (i < len) {
	        /* c1 */
	        do {
	            c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
	        } while (i < len && c1 == -1);
	        if (c1 == -1) break;
	
	        /* c2 */
	        do {
	            c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
	        } while (i < len && c2 == -1);
	        if (c2 == -1) break;
	
	        out[j++] = String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
	
	        /* c3 */
	        do {
	            c3 = str.charCodeAt(i++) & 0xff;
	            if (c3 == 61) return out.join('');
	            c3 = base64DecodeChars[c3];
	        } while (i < len && c3 == -1);
	        if (c3 == -1) break;
	
	        out[j++] = String.fromCharCode(((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2));
	
	        /* c4 */
	        do {
	            c4 = str.charCodeAt(i++) & 0xff;
	            if (c4 == 61) return out.join('');
	            c4 = base64DecodeChars[c4];
	        } while (i < len && c4 == -1);
	        if (c4 == -1) break;
	        out[j++] = String.fromCharCode(((c3 & 0x03) << 6) | c4);
	    }
	    return out.join('');
	}
};
/* utils | End */


/* debug | Begin */
NW3.debug = {};

NW3.debug.log = function(val) {
    if(val){
	    if(typeof(console) == 'undefined') {
	        alert(val);
	    }
	    else {
	        console.log(val);
	    }
    }
};

NW3.debug.printR = function( val, textFormat, return_val ) {
	var level = 0;
	
	var output = "", pad_char = " ", pad_val = 4;
 	
 	return_val = (return_val)?true:false;
 	
    formatArray = function (obj, cur_depth, pad_val, pad_char, level) {
        if (cur_depth > 0) {
            cur_depth++;
        }
 
        var base_pad = repeat_char(pad_val*cur_depth, pad_char);
        var thick_pad = repeat_char(pad_val*(cur_depth+1), pad_char);
        var str = "";
		
		if (NW3.core.array.isArray(obj) || NW3.core.object.isObject(obj)) {
			
			if(NW3.core.array.isArray(obj)) type = "Array";
			else if(NW3.core.object.isObject(obj)) type = "Object";
			str += type+"\n" + base_pad + "(";
			if(!textFormat) str += "<br />";
			str += "\n";
			
			level++;
			
			for (var key in obj) {
				if(!textFormat){
					for (l=0; (level-1)>=l; l++){
						if(!textFormat) str += "&nbsp;&nbsp;";
						str += "\t\t";
					}
				}
				if (NW3.core.array.isArray(obj[key]) || NW3.core.object.isObject(obj[key])) {
                    str += thick_pad + "["+key+"] => "+formatArray(obj[key], cur_depth+1, pad_val, pad_char, level);
                } else {
                    str += thick_pad+'['+key+'] => "'+obj[key]+'"';
					if(!textFormat) str += "<br />";
					str += "\n";
                }
            }
            
			for (l=0; (level-2)>=l; l++){
				if(!textFormat) str += "&nbsp;&nbsp;";
				//else str += "\t\t";
			}
            
            str += base_pad + ")";
			if(!textFormat) str += "<br />";
			str += "\n";
        } else {
            
        }
        return str;
    };
 
    var repeat_char = function (len, pad_char) {
        var str = "";
        for(var i=0; i < len; i++) { 
            str += pad_char; 
        };
        return str;
    };
    if(!NW3.core.string.isString(val)) output = formatArray(val, 0, pad_val, pad_char, level);
    else output = val;
 
 	if(!return_val) document.write(output);
    else return output;
};
/* debug | End */